package templateExcel;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TemplateUtils {

    private static Pattern ARRAY_PATTERN = Pattern.compile("((?<=[(,]|^) *([^\\[\\],()0-9_][^\\[\\],()_]*)(____ARRAY_EXPRISION_[0-9]+)? *(?=[,)]|$))");
    private static Pattern ARRAY_EXPRESSION_PATTERN = Pattern.compile("(\\[([^\\[\\]]+)])(\\[([^\\[\\]]+)])?");


    private static Pattern DOUBLE_QUOTES_PATTEN = Pattern.compile("\"[^\"]*\"");
    private static Pattern SINGLE_QUOTES_PATTEN = Pattern.compile("'[^']*'");

    //解析单元格中的数据
    public static TemplateCell parseTemplateCell(String s) {

        Stack<String> strings = new Stack<>();

        //名称和字符串内容
        Map<String, String> nameString = new HashMap<>();

        //替换所有被转译的字符串
        s = s.replaceAll("\\\\'", "____SINGLE_QUOTES_SYMBOL____");
        s = s.replaceAll("\\\\\"", "____DOUBLE_QUOTES_SYMBOL____");

        StringBuilder builder = new StringBuilder();

        int end = 0;

        //单引号字符串

        Matcher sqpm = SINGLE_QUOTES_PATTEN.matcher(s);

        int sn = 0;

        while (sqpm.find()) {
            String name = "_____STRING_NAME_" + (sn++);
            String st = sqpm.group();
            //放入字符串
            nameString.put(name, st);
            //压入栈中
            strings.push(name);

            builder.append(s, end, sqpm.start()).append(name);
            end = sqpm.end();
        }
        builder.append(s.substring(end));

        //更新字符串
        s = builder.toString();
        builder.delete(0, builder.length());


        Matcher dqpm = DOUBLE_QUOTES_PATTEN.matcher(s);
        end = 0;
        while (dqpm.find()) {
            String name = "_____STRING_NAME_" + (sn++);
            String st = dqpm.group();
            //放入字符串
            nameString.put(name, st);
            //压入栈中
            strings.push(name);

            builder.append(s, end, dqpm.start()).append(name);
            end = dqpm.end();
        }
        builder.append(s.substring(end));

        s = builder.toString();
        builder.delete(0, builder.length());
        //------字符串保护------

        //所有数组引用表达式
        Map<String, String[]> arrayQuotes = new HashMap<>();

        //数组表达式保护
        Matcher aepm = ARRAY_EXPRESSION_PATTERN.matcher(s);


        end = 0;
        while (aepm.find()) {
            String name = "____ARRAY_EXPRISION_" + (sn++);
            String st = aepm.group();

            String[] ae;

            if (aepm.group(4) == null) {
                ae = new String[1];
                ae[0] = aepm.group(2);
            } else {
                ae = new String[2];
                ae[0] = aepm.group(2);
                ae[1] = aepm.group(4);
            }

            //放入表达式中
            arrayQuotes.put(name, ae);

            builder.append(s, end, aepm.start()).append(name);
            end = aepm.end();
        }
        builder.append(s.substring(end));

        s = builder.toString();
        builder.delete(0, builder.length());

        Matcher matcher = ARRAY_PATTERN.matcher(s);


        TemplateCell cell = new TemplateCell();

        end = 0;
        while (matcher.find()) {

            builder.append(s, end, matcher.start());
            end = matcher.end();

            //一般变量引用
            if (matcher.group(3) == null) {
                ValueQuote quote = new ValueQuote();
                quote.setName(matcher.group(2));
                cell.addTemplateQuote(quote);
                builder.append(quote.getQuoteName());//放入变量引用
            } else {

                //数组引用
                String group = matcher.group(3);

                //解析出表达式
                String[] ep = arrayQuotes.get(group);

                if (ep.length == 1) {

                    //使用逗号分隔表达式
                    String[] split = ep[0].split(",");

                    LinearArrayQuote quote = new LinearArrayQuote();
                    quote.setName(matcher.group(2));

                    if (split.length > 2) {
                        if (split[2].equals("handleArray")) {
                            quote.setFirstIsVertical(false);
                        }
                    }

                    quote.setStartExpression(split[0]);
                    quote.setLenExpression(split[1]);

                    cell.addTemplateQuote(quote);
                    builder.append(quote.getQuoteName());

                } else {
                    DoubleDimensionalArrayQuote array = new DoubleDimensionalArrayQuote();
                    array.setName(matcher.group(2));

                    String[] split1 = ep[0].split(",");
                    String[] split2 = ep[1].split(",");

                    //计算纵横表达式
                    if (split1.length > 2 && split2.length > 2) {
                        if (!split1[2].equals(split2[2])) {
                            if (split1[2].equals("v")) {
                                array.setFirstIsVertical(false);
                            }
                        }
                    } else {
                        if (split1.length > 2 && !(split2.length > 2) && split1[2].equals("handleArray")) {
                            array.setFirstIsVertical(false);
                        } else if (split2.length > 2 && !(split1.length > 2) && split2[2].equals("v")) {
                            array.setFirstIsVertical(false);
                        }
                    }

                    array.setStartExpression1(split1[0]);
                    array.setLenExpression1(split1[1]);

                    array.setStartExpression2(split2[0]);
                    array.setLenExpression2(split2[1]);


                    cell.addTemplateQuote(array);
                    builder.append(array.getQuoteName());
                }

            }

        }


        builder.append(s.substring(end));
        s = builder.toString();

        //字符串还原
        while (!strings.empty()) {
            String name = strings.pop();
            String st = nameString.get(name);
            s = s.replace(name, st);
        }

        s = s.replace("____SINGLE_QUOTES_SYMBOL____", "\\\'");
        s = s.replace("____DOUBLE_QUOTES_SYMBOL____", "\\\"");

        //设置表达式
        cell.setExpression(s);

        return cell;

    }


    public static void main(String[] args) {
        TemplateCell cell = parseTemplateCell("concat(abc,array[0,$len1,v][0,20,handleArray],array1[0,100,v],'测\\\'试','测\\\"试')");

        System.out.println(cell.getExpression());
    }



}
